#include <iostream>
#ifdef DECORATOR
#include "Decorator/decorator.h"
#endif
#ifdef PROXY
#include "Proxy/proxy.h"
#endif // PROXY
#ifdef FACTORY_METHOD
#include "FactoryMethod/factorymethod.h"
#endif // FACTORY_METHOD
#ifdef PROTOTYPE
#include "Prototype/prototype.h"
#endif // PROTOTYPE
#ifdef TEMPLATE_METHOD
#include "TemplateMethod/templatemethod.h"
#endif // TEMPLATE_METHOD
#ifdef FACADE
#include "Facade/facade.h"
#endif // FACADE
#ifdef BUILDER
#include "Builder/builder.h"
#endif // BUILDER
#ifdef OBSERVER
#include "Observer/observer.h"
#endif // OBSERVER
#ifdef ABSTRACT_FACTORY
#include "AbstractFactory/abstractfactory.h"
#endif // ABSTRACT_FACTORY
#ifdef STATE
#include "State/state.h"
#endif
#ifdef ADAPTER
#include "Adapter/adapter.h"
#endif // ADAPTER
#ifdef MEMENTO
#include "Memento/memento.h"
#endif // MEMENTO
#ifdef COMPOSITE
#include "Composite/composite.h"
#endif // COMPOSITE
#ifdef ITERATOR
#include "Iterator/iterator.h"
#endif // ITERATOR
#ifdef SINGLETON
#include "Singleton/singleton.h"
#endif // SINGLETON
#ifdef BRIDGE
#include "Bridge/bridge.h"
#endif // BRIDGE
#ifdef COMMAND
#include "Command/command.h"
#endif // COMMAND
#ifdef CHAINOFRESPONSIBILITY
#include "ChainOfResponsibility/chainofresponsibility.h"
#endif // CHAINOFRESPONSIBILITY
#ifdef MEDIATOR
#include "Mediator/mediator.h"
#endif // MEDIATOR


int main()
{
#ifdef DECORATOR
    Person* per = new Person("Mr.Lu");
    SuitPants* sp = new SuitPants;
    SuitJacket* sj = new SuitJacket;
    Sneakers* sk = new Sneakers;

    sp->Decorator(per);
    sj->Decorator(sp);
    sk->Decorator(sj);
    sk->Show();
#endif // DECORATOR
#ifdef PROXY
    OptionProxy proxy("小红");
    proxy.GiveFlowers();
    proxy.GiveDoll();
    proxy.GiveSnacks();
#endif // PROXY
#ifdef FACTORY_METHOD
    OperationFactoryMethod* ofm = new FactoryMethodSub;
    OperationBase* ob = ofm->CreateOperation();
    ob->m_optNum1 = 1;
    ob->m_optNum2 = 2;
    std::cout << ob->m_optNum1 << " - " << ob->m_optNum2 << " = " << ob->GetResult() << std::endl;
#endif // FACTORY_METHOD
#ifdef PROTOTYPE
    CVitae* lu = new CVitae;
    lu->SetName("大鸟");
    lu->SetAge(21);
    lu->SetWorkExp1("2024/7-2024/12", "Neusoft");
    lu->SetWorkExp2("2025/3-2025/6", "zhiyuan");
    CVitae* a = (CVitae*)lu->Clone();
    a->SetWorkExp2("2025/3-2025/6", "ZY");
    CVitae* b = (CVitae*)lu->Clone();
    b->SetName("小菜");
    lu->Display();
    a->Display();
    b->Display();
    delete lu;
    delete a;
    delete b;
#endif // PROTOTYPE
#ifdef TEMPLATE_METHOD
    ExaminationPaperA epA;
    ExaminationPaperB epB;
    epA.Question1();
    epB.Question2();
    epB.Question1();
    epB.Question2();
#endif // TEMPLATE_METHOD
#ifdef FACADE
    CFacade facade;
    facade.MethodA();
    facade.MethodB();
#endif // FACADE
#ifdef BUILDER
    Builder* pBuilderA = new TranslateBuilderA;
    Director d(pBuilderA);
    d.Create();
#endif // BUILDER
#ifdef OBSERVER
    Boss laoLu;
    Effort xiaoZhang(&laoLu);
    Ease xiaoLi(&laoLu);
    laoLu.Add(&xiaoZhang);
    laoLu.Add(&xiaoLi);
    laoLu.Nodify();
    std::cout << "========华丽分割线========\n";
    laoLu.Remove(&xiaoLi);
    laoLu.Nodify();
    std::cout << "========华丽分割线========\n";
    Effort2 xw(&laoLu);
    Ease2 xs(&laoLu);
    Ease2 xx(&laoLu);
    laoLu.Add(&xw, &Effort2::Effort2Update);
    laoLu.Add(&xs, &Ease2::Ease2Update);    // 消息订阅不能为函数重载
    laoLu.Add(&xx, &Ease2::Ease2Update);
    laoLu.Nodify();
    std::cout << "========华丽分割线========\n";
    laoLu.Remove(&xx, &Ease2::Ease2Update);
    laoLu.Nodify();
#endif // OBSERVER
#ifdef ABSTRACT_FACTORY
    std::cout << "========抽象工厂模式========\n";
    DataBase::DBType = "Sqlite"; // Sqlite/MYSql 替换数据库类型就可以使用不同的数据库
    IUser* user = DataBase::CreateUser();
    IDepartment* depar = DataBase::CreateDepartment();
    user->Insert();
    depar->Insert();
    user->GetUser();
    depar->GetDepartment();
    std::cout << "========抽象工厂模式========\n";
#endif // ABSTRACT_FACTORY
#ifdef STATE
    std::cout << "========状态模式========\n";
    WokeSchedule woke;
    woke.SetState(new ForenoonState);
    woke.hour = 10;
    woke.ScheduleUpdate();
    woke.hour = 12;
    woke.ScheduleUpdate();
    woke.hour = 14;
    woke.ScheduleUpdate();
    woke.hour = 18;
    woke.ScheduleUpdate();
    woke.hour = 20;
    woke.ScheduleUpdate();

    woke.workFinish = true; // true强制下班
    woke.hour = 22;
    woke.ScheduleUpdate();
    std::cout << "========状态模式========\n";
#endif // STATE
#ifdef ADAPTER
    std::cout << "========适配器模式========\n";
    Player* laowang = new Forward("老王");
    Player* yaoming = new Adepter("姚明");
    Player* laoli = new Guard("老李");
    laowang->Offense();
    yaoming->Defense();
    laoli->Offense();
    laowang->Defense();
    yaoming->Offense();
    laoli->Offense();
    std::cout << "========适配器模式========\n";
#endif // ADAPTER
#ifdef MEMENTO
    std::cout << "========备忘录模式========\n";
    GameRole yifeng(100, 100, 100);
    yifeng.ShowState();
    MementoManager memeMgr;
    memeMgr.m_memen = yifeng.SaveState();
    yifeng.Combat();
    yifeng.ShowState();
    yifeng.RecoveryState(*memeMgr.m_memen);
    yifeng.ShowState();
    std::cout << "========备忘录模式========\n";
#endif // MEMENTO
#ifdef COMPOSITE
    std::cout << "========组合模式========\n";
    Company* root = new Company("老任有限公司");
    root->Add(new Treasury("总公司财务部"));
    root->Add(new HumanResource("总公司人力资源部"));
    Company* hzSubCom = new Company("杭州分公司");
    hzSubCom->Add(new Treasury("杭州财务部"));
    hzSubCom->Add(new HumanResource("杭州人力资源部"));
    root->Add(hzSubCom);
    Company* bjSubCom = new Company("杭州滨江办事处");
    bjSubCom->Add(new Treasury("滨江财务部"));
    bjSubCom->Add(new HumanResource("滨江人力资源部"));
    hzSubCom->Add(bjSubCom);
    root->ShowCompanyOrganic(1);
    root->Process();
    // 移除滨江办事处
    hzSubCom->Remote(bjSubCom);
    root->ShowCompanyOrganic(1);
    root->Process();
    std::cout << "========组合模式========\n";
#endif // COMPOSITE
#ifdef ITERATOR
    std::cout << "========迭代器模式========\n";
    IntArray arr;
    IntArray::PIterator it = arr.CreateIteratorPointer();
    while (!it->IsEmpty())
    {
        std::cout << *it->GetItem() << ',';
        it->Next(2);
    }
    std::cout << std::endl;
    auto saIt = arr.CreateSAIteratorPointer();
    while (!saIt->IsEmpty()) {
        std::cout << *saIt->GetItem() << ',';
        saIt->Next();
    }
    std::cout << std::endl;
    std::cout << "========迭代器模式========\n";
#endif // ITERATOR
#ifdef SINGLETON
    std::cout << "========单例模式========\n";
    CSingletonLazy* lazyIns = CSingletonLazy::GetInstance();
    CSingletonLazy* lazyIns1 = CSingletonLazy::GetInstance();
    if (lazyIns == lazyIns1) {
        std::cout << "懒汉式对象一致\n";
    }
    CSingletonHungry* hunIns = CSingletonHungry::GetInstance();
    CSingletonHungry* hunIns1 = CSingletonHungry::GetInstance();
    if (hunIns == hunIns1) {
        std::cout << "饿汉式对象一致\n";
    }
    std::cout << "========单例模式========\n";
#endif // SINGLETON
#ifdef BRIDGE
    std::cout << "========桥接模式========\n";
    HandsetBrand* ab = new HandsetBrandA;
    ab->SetSoft(new HandsetGameSoftA);
    ab->Run();
    ab->SetSoft(new HandsetAddressListSoftA);
    ab->Run();
    ab = new HandsetBrandB;
    ab->SetSoft(new HandsetGameSoftB);
    ab->Run();
    ab->SetSoft(new HandsetAddressListSoftB);
    ab->Run();
    std::cout << "========桥接模式========\n";
#endif // BRIDGE
#ifdef COMMAND
    std::cout << "========命令模式========\n";
    Barbecuer bar;
    MuttonShashlikCommand mutton1(&bar);
    MuttonShashlikCommand mutton2(&bar);
    ChickenWingCommand chicken1(&bar);
    Waiter waiter;
    waiter.AddRecord(&mutton1);
    waiter.AddRecord(&mutton2);
    waiter.AddRecord(&chicken1);
    waiter.Notify();
    waiter.RemoteRecord(&mutton2);
    waiter.Notify();
    std::cout << "========命令模式========\n";
#endif // COMMAND
#ifdef CHAINOFRESPONSIBILITY
    std::cout << "========职责链模式========\n";
    COPTeamLeader tl("组长");
    COPDirector dir("总监");
    COPChairman lc("鲁总");
    tl.SetSuperior(&dir);
    dir.SetSuperior(&lc);
    tl.HandleApplication("加薪", 500);
    tl.HandleApplication("加薪", 1500);
    tl.HandleApplication("加薪", 2000);
    tl.HandleApplication("加薪", 2500);
    std::cout << "========职责链模式========\n";
#endif // CHAINOFRESPONSIBILITY
#ifdef MEDIATOR
    std::cout << "========中介者模式========\n";
    SecurityCouncil sc;
    USA usa(&sc);
    Iran iran(&sc);
    sc.SetUSA(&usa);
    sc.SetIran(&iran);
    usa.Publish("不准研制核武器，否则要发动战争！");
    iran.Publish("我们没有核武器，也不怕侵略！");
    std::cout << "========中介者模式========\n";
#endif // MEDIATOR



    return 0;
}